package com.litaomn.fang.hotload;

import android.content.Context;

import com.google.common.collect.Lists;
import com.tencent.mm.fang.FangBridge;
import com.tencent.mm.fang.callbacks.XC_LoadPackage;

import org.apache.commons.io.IOUtils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Collections;
import java.util.List;


public class HotLoadEntry {
    public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam, Context context) throws Throwable {
        SO.master = context.getClassLoader();
        SO.lpparam = loadPackageParam;
        SO.plugin = this.getClass().getClassLoader();
        SO.context = context;
        //让所有的程序可以debug
        //EnableDebugHook.enableDebug();
        //显示界面信息
        //DroidSword.startDroidSword();
        //异步监控
        //ThreadHook.monitorThreadPool();
        //悬浮球
        //SonnyJackDragView.enableDragViewPanel();
        List<FangHotLoadCallBack> allCallBack = findAllCallBack();
        for (FangHotLoadCallBack fangHotLoadCallBack : allCallBack) {
            if (fangHotLoadCallBack == null) {
                continue;
            }
            try {
                //FangBridge.log("执行回调: " + fangHotLoadCallBack.getClass());
                fangHotLoadCallBack.onFangHotLoad();
            } catch (Exception e) {
                FangBridge.log(e);
            }
        }
    }


    private static List<FangHotLoadCallBack> findAllCallBack() {
        InputStream stream = SO.plugin.getResourceAsStream("assets/entry");
        if (stream == null) {
            //cancel log print,because the code will execute for all app process
            FangBridge.log("can not find entry.txt,please check");
            return Collections.emptyList();
        }
        List<FangHotLoadCallBack> result = Lists.newLinkedList();
        try {
            BufferedReader moduleClassesReader = new BufferedReader(new InputStreamReader(stream));
            String moduleClassName;
            while ((moduleClassName = moduleClassesReader.readLine()) != null) {
                moduleClassName = moduleClassName.trim();
                //ignore blank
                if (moduleClassName.isEmpty()) {
                    continue;
                }
                //ignore for comment
                if (moduleClassName.startsWith("#")) {
                    continue;
                }
                //ignore for action
                if (moduleClassName.startsWith("action:")) {
                    continue;
                }
                try {
                    Class<?> moduleClass = SO.plugin.loadClass(moduleClassName);

                    if (!FangHotLoadCallBack.class.isAssignableFrom(moduleClass)) {
                        FangBridge.log("    This class doesn't implement any sub-interface of FangHotLoadCallBack, skipping it");
                        continue;
                    }
                    FangHotLoadCallBack moduleInstance = (FangHotLoadCallBack) moduleClass.newInstance();
                    if (moduleInstance.needHook(SO.lpparam)) {
                        result.add(moduleInstance);
                    }

                } catch (Throwable t) {
                    FangBridge.log("    Failed to load class " + moduleClassName);
                    FangBridge.log(t);
                }
            }
        } catch (IOException e) {
            FangBridge.log("load hot plugin failed");
            FangBridge.log(e);
        } finally {
            IOUtils.closeQuietly(stream);
        }
        return result;
    }
}
